/*******************************************************************************
* Copyright (c) 2009 Chris Horneck and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Chris Horneck - initial API and implementation (bug 287765)
*******************************************************************************/
package org.eclipse.jface.tests.viewers;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Shell;
/**
* @since 3.4
*
*/
public class Bug287765Test extends TestCase {
private TreeViewer treeViewer;
private Node root;
/**
* An element in the Tree. Knows about its children and parent.
*/
private static class Node {
private final Node parent;
private final List children = new ArrayList();
private final int level;
private Node(Node parentNode, int nodeLevel) {
this.parent = parentNode;
this.level = nodeLevel;
if (parent != null) {
parent.children.add(this);
}
}
}
private final class SimpleTreeContentProvider implements
ITreeContentProvider, ILabelProvider {
@Override
public Image getImage(Object element) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getText(Object element) {
Node node = (Node) element;
return Integer.toString(node.level);
}
@Override
public void addListener(ILabelProviderListener listener) {
}
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {
}
@Override
public Object[] getChildren(Object parentElement) {
Node node = (Node) parentElement;
return node.children.toArray();
}
@Override
public boolean hasChildren(Object element) {
Node node = (Node) element;
return node.children.size() > 0;
}
@Override
public Object[] getElements(Object inputElement) {
int depth = 4;
Node node = new Node(root, 1);
Node parentNode = node;
for (int i = 2; i <= depth; i++) {
Node newNode = new Node(parentNode, i);
parentNode = newNode;
}
return new Object[] { node };
}
@Override
public Object getParent(Object element) {
Node node = (Node) element;
return node.parent;
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
final Shell shell = new Shell();
shell.setLayout(new GridLayout());
shell.setSize(new Point(500, 200));
treeViewer = new TreeViewer(shell);
treeViewer.getControl().setLayoutData(
new GridData(SWT.FILL, SWT.FILL, true, true));
/*
* This is a key element to reproducing this bug. It causes
* AbstractTreeViewer#disassociate to recurse when it is disassociating
* TreeItems. This causes the data field in all of the TreeItems to get
* cleared out.
*/
treeViewer.setUseHashlookup(true);
SimpleTreeContentProvider provider = new SimpleTreeContentProvider();
treeViewer.setContentProvider(provider);
treeViewer.setLabelProvider(provider);
root = new Node(null, 0);
treeViewer.setInput(root);
shell.open();
}
@Override
protected void tearDown() throws Exception {
treeViewer.getControl().getShell().dispose();
treeViewer = null;
root = null;
super.tearDown();
}
/**
* Test to make the bug occur
*/
public void testException() {
// Expand all the nodes
treeViewer.expandAll();
// Refresh the tree to generate new nodes
treeViewer.refresh();
// Retrieve the expanded paths
treeViewer.getExpandedTreePaths();
}
}